import config from './config';
import { login } from "../service/user";

const codeStatus = {
    0(res) {
        return res
    },
    async 4001(res) {
        wx.removeStorageSync('token');
        await login()
        wx.showToast({
            title: '请稍后重试',
            icon: 'none'
        })
        return Promise.reject(res)
    },
};

export const requestBase = (url, data = {}, method = 'post') => {
    return new Promise((resolve, reject) => {
        wx.request({
            url: `${config.requestBaseUrl}${url}`,
            data,
            method,
            header: {
                token: wx.getStorageSync('token'),
            },
            success(res) {
                resolve(res)
            },
            fail(res) {
                reject(res)
            }
        })
    }).then(res => {
        if (codeStatus[res.data.code]) {
            return codeStatus[res.data.code].call(this, res)
        } else {
            return Promise.reject(res)
        }
    }).catch(res => {
        return new Promise((resolve, reject) => {
            if (res.data.msg) {
                wx.showToast({
                    title: res.data.msg,
                    icon: 'none',
                    duration: 1500,
                    success() {
                        setTimeout(() => reject(res), 1500)
                    }
                });
            } else {
                reject(res)
            }
        })
    })
}

export class useRequest {
    constructor(url, options = {}, pageOrComponent = null) {
        this.url = url;
        this.data = null;
        this.loading = false;
        this.options = Object.assign({
            // 参数
            params: {},
            // 是否加载
            loading: 'loading',
            // 错误
            error: null,
            // 数据
            data: null,
            // 请求方式
            method: 'post',
            // 是否初始化就请求
            hold: false,
            // 预处理
            pretreatment: data => data
        }, options);
        this.page = pageOrComponent

        if (!this.options.hold) this.run().then()
    }

    /**
     * 手动运行
     * @param params
     * @returns {Promise}
     */
    run(params = null) {
        this.page && this.page.setData({
            [this.options.loading]: true
        })
        if (params) this.options.params = params
        return requestBase(
            this.url,
            this.options.params,
            this.options.method
        ).then(res => {
            console.log(this.url, this.options.params, res.data)

            const setData = {}
            const data = this.options.pretreatment(res.data.data)
            if (this.options.loading) setData[this.options.loading] = false
            if (this.options.data) setData[this.options.data] = data
            this.page && this.page.setData(setData)
            return data
        }).catch(res => {
            console.warn(this.url, this.options.params, res.data)

            const setData = {}
            if (this.options.loading) setData[this.options.loading] = false
            if (this.options.error) setData[this.options.error] = res
            this.page && this.page.setData(setData)
            return Promise.reject(res)
        })
    }
}

export class usePageRequest {
    constructor(url, options, pageOrComponent) {
        // 保存参数
        this.url = url
        this.options = Object.assign({
            // 参数
            params: {},
            // 是否加载
            loading: 'loading',
            // 错误
            error: null,
            // 数据
            data: 'data',
            // 请求方式
            method: 'post',
            // 是否初始化就请求
            hold: false,
            // 预处理
            pretreatment: data => data,
            // 传过去的参数
            size: 'size',
            page: 'page',
            // 传回来的参数
            end: 'end',
            totalPages: 'total_page',
            // 默认初始化的页数页码
            pageNumber: 1,
            pageSize: 20
        }, options);
        this.pageOrComponent = pageOrComponent

        // 初始化页面数
        this.page = this.options.pageNumber
        this.size = this.options.pageSize
        this.end = false

        this.request = new useRequest(url, {
            pretreatment: this.options.pretreatment,
            method: this.options.method,
            hold: true,
        })
        if (!this.options.hold) {
            this.next()
        }
    }

    /**
     * 下一页
     */
    next(params) {
        if (params) this.options.params = params
        if (!this.end) {
            this.options.loading && this.pageOrComponent.setData({
                [this.options.loading]: true
            })
            return this.request.run({
                ...this.options.params,
                [this.options.size]: this.size,
                [this.options.page]: this.page++
            }).then(data => {
                if (this.page >= data[this.options.totalPages]) {
                    this.end = true
                }
                this.pageOrComponent.setData({
                    [this.options.data]: [...this.pageOrComponent.data[this.options.data] || [], ...data.list]
                })
            }).catch(error => {
                const setData = {}
                if (this.options.error) setData[this.options.error] = error
                this.pageOrComponent.setData(setData)
            }).finally(() => {
                this.options.loading && this.pageOrComponent.setData({
                    [this.options.loading]: false
                })
            })
        }
    }

    /**
     * 重置
     * @param params
     */
    reset(params = null) {
        this.page = 1;
        this.end = false
        this.pageOrComponent.setData({
            [this.options.data]: []
        })
        return this.next(params)
    }
}

/**
 * 上传图片
 * @param filePath
 * @param showLoading
 * @returns {Promise}
 */
export function upload(filePath, showLoading = true) {
    showLoading && wx.showLoading({
        title: '正在上传中'
    })
    return new Promise((resolve, reject) => {
        wx.uploadFile({
            url: `${config.requestBaseUrl}api/upload`,
            name: 'file',
            filePath,
            success(e) {
                resolve(JSON.parse(e.data).data[0])
            },
            fail() {
                reject()
            },
            complete() {
                showLoading && wx.hideLoading()
            }
        })
    })
}
